﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace Shell
{
    internal class LifetimeContainer : ILifetimeContainer
    {
        private readonly List<object> items;

        public LifetimeContainer()
        {
            this.items = new List<object>();
        }

        public int Count
        {
            get { lock (this.items) { return this.items.Count; } }
        }

        public bool Contains(object item)
        {
            lock (this.items)
            {
                return this.items.Contains(item);
            }
        }

        public void Add(object item)
        {
            lock (this.items)
            {
                this.items.Add(item);
            }
        }

        public void Remove(object item)
        {
            lock (this.items)
            {
                if (this.items.Contains(item))
                {
                    this.items.Remove(item);
                }
            }
        }

        public void Clear()
        {
            lock (this.items)
            {
                this.items.Clear();
            }
        }

        public IEnumerator<object> GetEnumerator()
        {
            return this.items.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                lock (this.items)
                {
                    var itemsCopy = new List<object>(this.items);
                    itemsCopy.Reverse();

                    foreach (object o in itemsCopy)
                    {
                        if (o is IDisposable)
                        {
                            var d = o as IDisposable;
                            d.Dispose();
                        }
                    }
                    items.Clear();
                }
            }
        }
    }
}
